package com.dkts.oil.test;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.apache.commons.math3.ml.clustering.DBSCANClusterer;
import org.apache.commons.math3.ml.clustering.Cluster;
import org.apache.commons.math3.ml.clustering.DoublePoint;

import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.stream.Collectors;

public class AISTrajectorySegmenter {

    private static final double DISTANCE_THRESHOLD = 0.3; // 30公里，约为0.27度
    private static final int TIME_THRESHOLD = 40 * 60; // 40分钟，单位为秒

    public static void main(String[] args) throws Exception {
        // CSV 文件路径
        File csvFile = new File("C:\\Users\\heyou\\Documents\\WeChat Files\\wxid_86da35bc9zvi21\\FileStorage\\File\\2025-05\\c9a6717b7d2f5293cf7cd2ed05a0494c_2e2437ef9cd58c0d39af05569deeb4be_8.csv");
        Reader reader = new FileReader(csvFile);

        CSVParser parser = CSVFormat.DEFAULT.withFirstRecordAsHeader().parse(reader);

        // 存储 MMSI 对应的轨迹点
        Map<String, List<CSVRecord>> mmsiMap = new HashMap<>();
        for (CSVRecord record : parser) {
            String mmsi = record.get("mmsi");
            mmsiMap.computeIfAbsent(mmsi, k -> new ArrayList<>()).add(record);
        }

        // 创建 ObjectMapper 用于写入 GeoJSON
        ObjectMapper mapper = new ObjectMapper();

        // 遍历每个 MMSI，分割并分析轨迹
        for (Map.Entry<String, List<CSVRecord>> entry : mmsiMap.entrySet()) {
            String mmsi = entry.getKey();
            List<CSVRecord> records = entry.getValue();
            if (records.size() < 2) continue;

            // 对轨迹按照时间排序
            records.sort(Comparator.comparing(r -> r.get("time")));

            // 提取轨迹点
            List<DoublePoint> points = new ArrayList<>();
            for (CSVRecord record : records) {
                double lon = Double.parseDouble(record.get("lon"));
                double lat = Double.parseDouble(record.get("lat"));
                points.add(new DoublePoint(new double[]{lon, lat}));
            }

            // 使用 DBSCAN 聚类算法分割编队
            DBSCANClusterer<DoublePoint> clusterer = new DBSCANClusterer<>(DISTANCE_THRESHOLD, 10);
            List<Cluster<DoublePoint>> clusters = clusterer.cluster(points);

            // 为每个编队创建一个文件夹和 GeoJSON 文件
            for (int clusterIndex = 0; clusterIndex < clusters.size(); clusterIndex++) {
                Cluster<DoublePoint> cluster = clusters.get(clusterIndex);
                if (cluster.getPoints().size() < 2) continue; // 编队点数小于2个不处理

                // 创建编队文件夹
                Path folderPath = Paths.get("output/" + mmsi + "/cluster_" + clusterIndex);
                Files.createDirectories(folderPath);

                // 创建 GeoJSON 文件
                File geojsonFile = new File(folderPath.toFile(), "trajectory.geojson");
                FileWriter writer = new FileWriter(geojsonFile);
                ArrayNode featureCollection = mapper.createArrayNode();

                // 生成 GeoJSON 特征
                ObjectNode feature = mapper.createObjectNode();
                feature.put("type", "Feature");

                // 生成 LineString 轨迹
                ObjectNode geometry = mapper.createObjectNode();
                geometry.put("type", "LineString");
                ArrayNode coordinates = mapper.createArrayNode();

                // 为每个轨迹点添加到 LineString 中
                for (DoublePoint point : cluster.getPoints()) {
                    coordinates.add(point.getPoint()[0]);  // 经度
                    coordinates.add(point.getPoint()[1]);  // 纬度
                }

                geometry.set("coordinates", coordinates);
                feature.set("geometry", geometry);

                // 属性信息（根据需要自定义）
                ObjectNode properties = mapper.createObjectNode();
                properties.put("mmsi", mmsi);
                feature.set("properties", properties);

                featureCollection.add(feature);

                // 写入 GeoJSON 文件
                writer.write(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(featureCollection));
                writer.close();

                System.out.println("GeoJSON 文件已生成：" + geojsonFile.getAbsolutePath());
            }
        }
    }
}
